package helper;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;

public class ZipHandler {
	
	public ZipHandler() {
		fileList = new ArrayList<String>();
	}
	
	public void unzip(File inputZip, File outputFolder) {
		byte[] buffer = new byte[1024];
		
		try {
			
			// create output directory is not exists
			if (!outputFolder.exists()) {
				outputFolder.mkdir();
			}
			
			// get the zip file content
			ZipInputStream zis = new ZipInputStream(new FileInputStream(inputZip));
			// get the zipped file list entry
			ZipEntry ze = zis.getNextEntry();
			
			while (ze != null) {
				
				String fileName = ze.getName();
				File newFile = new File(outputFolder + File.separator + fileName);
				
				// System.out.println("file unzip : " + newFile.getAbsoluteFile());
				
				// create all non exists folders
				// else you will hit FileNotFoundException for compressed folder
				new File(newFile.getParent()).mkdirs();
				
				FileOutputStream fos = new FileOutputStream(newFile);
				
				int len;
				while ((len = zis.read(buffer)) > 0) {
					fos.write(buffer, 0, len);
				}
				
				fos.close();
				
				ze = zis.getNextEntry();
			}
			
			zis.closeEntry();
			zis.close();
			
			// System.out.println("Done");
			
		} catch (IOException ex) {
			ex.printStackTrace();
		}
	}
	
	private List<String> fileList;
	
	public void zip(File sourceDir, File toZip) {
		
		generateFileList(sourceDir, sourceDir);
		
		byte[] buffer = new byte[1024];
		
		try {
			
			FileOutputStream fos = new FileOutputStream(toZip);
			ZipOutputStream zos = new ZipOutputStream(fos);
			
			// System.out.println("Output to Zip : " + toZip.getPath());
			
			for (String file : this.fileList) {
				
//				System.out.println("File Added : " + file);
				ZipEntry ze = new ZipEntry(file);
				zos.putNextEntry(ze);
				
				FileInputStream fis = new FileInputStream(sourceDir.getAbsolutePath() + File.separator + file);
				
				int len;
				while ((len = fis.read(buffer)) > 0) {
					zos.write(buffer, 0, len);
				}
				
				fis.close();
			}
			
			zos.closeEntry();
			zos.close();
			
			// System.out.println("Done");
		} catch (IOException ex) {
			ex.printStackTrace();
		}
	}
	
	private void generateFileList(File node, File rootDir) {
		
		// add file only
		if (node.isFile()) {
			fileList.add(generateZipEntry(node.getAbsoluteFile().toString(), rootDir));
		}
		
		if (node.isDirectory()) {
			String[] subNote = node.list();
			for (String filename : subNote) {
				generateFileList(new File(node, filename), rootDir);
			}
		}
		
	}
	
	private String generateZipEntry(String file, File rootDir) {
		return file.substring(rootDir.getAbsolutePath().length() + 1, file.length());
	}
}
